# @FileName  :  student.py
# @Time      :  2025/7/29 11:05
# @Author    :  Ayanami
# @info      :  学生相关的CRUD操作

from typing import Optional, List
from tortoise.expressions import Q, F
# from tortoise.queryset import QuerySet
from app.models.models import Student
from app.schemas.student import StudentCreate, StudentUpdate


class StudentCRUD:

    @staticmethod
    async def get_by_id(student_id: int) -> Optional[Student]:
        """根据ID获取学生"""
        return await Student.filter(id=student_id, is_deleted=False).prefetch_related("area", "source").first()

    @staticmethod
    async def get_by_student_id(student_id: str) -> Optional[Student]:
        """根据学号获取学生"""
        return await Student.filter(student_id=student_id, is_deleted=False).prefetch_related("area", "source").first()

    @staticmethod
    async def get_by_id_card(id_card: str) -> Optional[Student]:
        """根据身份证号获取学生"""
        return await Student.filter(id_card=id_card, is_deleted=False).prefetch_related("area", "source").first()

    @staticmethod
    async def create(student_data: StudentCreate) -> Student:
        """创建学生"""
        student_dict = student_data.model_dump()
        student = await Student.create(**student_dict)
        await student.fetch_related("area", "source")
        return student

    @staticmethod
    async def update(student_id: int, student_data: StudentUpdate) -> Optional[Student]:
        """更新学生信息"""
        student = await Student.filter(id=student_id, is_deleted=False).prefetch_related("area", "source").first()
        if not student:
            return None

        update_data = student_data.model_dump(exclude_unset=True)
        if update_data:
            await Student.filter(id=student_id, is_deleted=False).update(**update_data)
            student = await Student.filter(id=student_id, is_deleted=False).prefetch_related("area", "source").first()

        return student

    @staticmethod
    async def delete(s_id: int) -> bool:
        """删除学生"""
        student = await Student.get_or_none(id=s_id, is_deleted=False)
        student.is_deleted = True
        await student.save(update_fields=["is_deleted", "updated_at"])
        return True

    @staticmethod
    async def get_list(
            skip: int = 0,
            limit: int = 20,
            search: Optional[str] = None,
            area_id: Optional[int] = None,
            gender: Optional[str] = None,
            is_verified: Optional[bool] = None
    ) -> tuple[List[Student], int]:
        """获取学生列表"""
        query = Student.filter(is_deleted=False).prefetch_related("area", "source")

        # 搜索条件
        if search:
            query = query.filter(
                Q(name__icontains=search, is_deleted=False) |
                Q(student_id__icontains=search, is_deleted=False) |
                Q(phone__icontains=search, is_deleted=False) |
                Q(id_card__icontains=search, is_deleted=False)
            )

        if area_id:
            query = query.filter(area_id=area_id, is_deleted=False)

        if gender:
            query = query.filter(gender=gender, is_deleted=False)

        if is_verified is not None:
            query = query.filter(is_verified=is_verified, is_deleted=False)

        # 获取总数
        total = await query.count()

        # 分页
        students = await query.offset(skip).limit(limit).order_by("-created_at")

        return students, total

    @staticmethod
    async def update_study_hours(student_id: int, hours: int) -> bool:
        """更新学习时长"""
        updated_count = await Student.filter(id=student_id, is_deleted=False).update(
            total_study_hours=F("total_study_hours") + hours
        )
        return updated_count > 0

    @staticmethod
    async def update_honors_count(student_id: int, count: int) -> bool:
        """更新荣誉数量"""
        updated_count = await Student.filter(id=student_id, is_deleted=False).update(
            honors_count=F("honors_count") + count
        )
        return updated_count > 0

    @staticmethod
    async def verify_student(student_id: int) -> bool:
        """实名认证学生"""
        updated_count = await Student.filter(id=student_id, is_deleted=False).update(is_verified=True)
        return updated_count > 0


student_crud = StudentCRUD()